package com.blue.gateway.paycore.wxpay.pay;

import com.alibaba.fastjson.JSON;
import com.blue.gateway.common.Request;
import com.blue.gateway.config.BaseChannelConfig;
import com.blue.gateway.dto.Result;
import com.blue.gateway.dto.ResultWrapper;
import com.blue.gateway.enums.PayChannelEnum;
import com.blue.gateway.utils.BigDecimalUtil;
import com.blue.gateway.utils.RandomUtil;
import com.blue.gateway.utils.http.HttpClientsUtil;
import com.blue.gateway.utils.sign.WxPaySignature;
import com.blue.gateway.annotation.Channel;
import com.blue.gateway.common.request.PayRequest;
import com.blue.gateway.common.response.PayResponse;
import com.blue.gateway.config.WxConfig;
import com.blue.gateway.paycore.wxpay.WxPayConstants;
import com.blue.gateway.enums.ServiceChannelEnum;
import com.blue.gateway.utils.XmlUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * @author xiaoyiming
 * @date 2020/5/4 23:58
 * @depiction 微信支付接口
 * H5支付:https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_20&index=1
 * 整体流程和常见问题:https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_4
 */
@Slf4j
@Channel(PayChannel = PayChannelEnum.WX_H5, ServiceChannel = ServiceChannelEnum.PAY)
public class WxPayH5Service extends WxPayService {

    @Override
    public Result validate(Request request) {
        return super.validate(request);
    }


    @Override
    public BaseChannelConfig getConfig(Request request) {
        return super.getConfig(request);
    }

    /**
     * <xml>
     * <appid>wxd898fcb01713c658</appid>
     * <body><![CDATA[测试一下]]></body>
     * <mch_id>1483469312</mch_id>
     * <nonce_str>SQdyiAF3qp3UV4F3</nonce_str>
     * <notify_url>http://vqcjt4.natappfree.cc/notify_wx</notify_url>
     * <out_trade_no>27809811237111</out_trade_no>
     * <scene_info>{\"h5_info\":\"{\\\"wap_name\\\":\\\"测试一下\\\",\\\"wap_url\\\":\\\"http://vqcjt4.natappfree.cc/return\\\",\\\"type\\\":\\\"Wap\\\"}\"}</scene_info>
     * <sign><![CDATA[125BBFF5B9424DDF0721A588A9230747]]></sign>
     * <spbill_create_ip>8.8.8.8</spbill_create_ip>
     * <total_fee>1</total_fee>
     * <trade_type>MWEB</trade_type>
     * </xml>
     *
     * @param request
     * @param channelConfig
     * @return
     */
    @Override
    public String generateParams(Request request, BaseChannelConfig channelConfig) {
        PayRequest payRequest = (PayRequest) request;
        WxConfig wxConfig = (WxConfig) channelConfig;

        SortedMap<String, String> params = new TreeMap<>();
        params.put("appid", wxConfig.getAppId());
        params.put("mch_id", wxConfig.getMchId());
        params.put("nonce_str", RandomUtil.getRandomStr());
        params.put("body", payRequest.getSubject());
        params.put("out_trade_no", payRequest.getOutTradeNo());
        params.put("total_fee", BigDecimalUtil.toUnitFen(payRequest.getTotalAmount()));
        params.put("spbill_create_ip", payRequest.getSpbillCreateIp());
        params.put("notify_url", payRequest.getNotifyUrl());
        params.put("trade_type", WxPayConstants.TRADE_TYPE_H5);
        //场景信息
        //IOS移动应用 {"h5_info": {"type":"IOS","app_name": "王者荣耀","bundle_id": "com.tencent.wzryIOS"}}
        //安卓移动应用 {"h5_info": {"type":"Android","app_name": "王者荣耀","package_name": "com.tencent.tmgp.sgame"}}
        //WAP网站应用 {"h5_info": {"type":"Wap","wap_url": "https://pay.qq.com","wap_name": "腾讯充值"}}
        Map<String, String> sceneInfo = new HashMap<>();
        Map<String, String> h5Info = new HashMap<>();
        h5Info.put("type", "Wap");
        h5Info.put("wap_url", payRequest.getReturnUrl());
        h5Info.put("wap_name", payRequest.getSubject());
        sceneInfo.put("h5_info", JSON.toJSONString(h5Info));
        params.put("scene_info", JSON.toJSONString(sceneInfo));

        String sign = WxPaySignature.sign(params, wxConfig.getParterKey());
        params.put("sign", sign);
        return XmlUtil.mapToXML(params);
    }

    @Override
    public String execute(String requestParams, BaseChannelConfig channelConfig) {
        // 发送请求
        String executeResult = null;
        try {
            executeResult = HttpClientsUtil.httpClientPost(WxPayConstants.WX_PAY_GATEWAY, requestParams);
        } catch (Exception e) {
            // do nothing
        }
        return executeResult;
    }

    /**
     * <xml>
     * <return_code><![CDATA[SUCCESS]]></return_code>\n
     * <return_msg><![CDATA[OK]]></return_msg>\n
     * <appid><![CDATA[wxd898fcb01713c658]]></appid>\n
     * <mch_id><![CDATA[1483469312]]></mch_id>\n
     * <nonce_str><![CDATA[d7J8a4qDvoFlqWFp]]></nonce_str>\n
     * <sign><![CDATA[8B5AB79CD987F97C8EB60D3EBAF3EF6B]]></sign>\n
     * <result_code><![CDATA[SUCCESS]]></result_code>\n
     * <prepay_id><![CDATA[wx051752572149749b55abee1b1614936500]]></prepay_id>\n
     * <trade_type><![CDATA[MWEB]]></trade_type>\n
     * <mweb_url><![CDATA[https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx051752572149749b55abee1b1614936500&package=2399961488]]></mweb_url>\n
     * </xml>
     *
     * @return
     */
    @Override
    public Result analysisResult(String executeResult) {
        PayResponse payResponse = new PayResponse();
        Map<String, String> result = XmlUtil.toMap(executeResult);
        payResponse.setMsg(result.get("return_msg"));
        payResponse.setData(JSON.toJSONString(result));
        if (WxPayConstants.SUCCESS.equals(result.get("return_code"))) {
            payResponse.setPayUrl(result.get("mweb_url"));
            return ResultWrapper.success(payResponse);
        }

        return ResultWrapper.fail(payResponse);
    }
}
